#include "frame.h"
#include "database.h"
#include <getopt.h>

pthread_key_t mysql_key;
static DATA_CALLBACK g_pfn_data_callback = NULL;

void closedb(void *args)
{
  MYSQL *mysql = (MYSQL *)args;
  close_db();
}



int getoption(int argc,const char **argv,struct srvcnf *pconf)
{
  int c;
  pconf->port = 6003;
  pconf->dbport = 3306;
  pconf->maxconns = 3000;
  pconf->workthreadnum = 1;
  pconf->loglevel = 3;
  pconf->daemonmode = 1;
  char short_options[] = {"vp:"};
  struct option long_options[] =
  {
       {"verbose", no_argument, &(pconf->daemonmode), 0},
       {"dbhost", required_argument, 0, 'b'},
       {"dbport", optional_argument, 0, 'e'},
       {"dbname", required_argument, 0, 'n'},
       {"dbuser", required_argument, 0, 'u'},
       {"dbpass", required_argument, 0, 's'},
       {"maxconn", optional_argument, 0, 'm'},
       {"workers", optional_argument, 0, 'w'},
       {"loglevel", optional_argument, 0, 'l'},
       {"desc", optional_argument, 0, 'd'},
       {0, 0, 0, 0}
  };

  while((c = getopt_long (argc, argv, short_options, long_options, NULL)) != -1)
  {
    switch (c){
      case 'p':
        pconf->port = atoi(optarg);
        break;
      case 'v':
        printf("version 1.0.0.0\n");
        break;
      case 'b':
        strcpy(pconf->dbserver,optarg);
        break;
      case 'e':
        pconf->dbport = atoi(optarg);
        break;
      case 'n':
        strcpy(pconf->default_database,optarg);
        break;
      case 'u':
        strcpy(pconf->dbuser,optarg);
        break;
      case 's':
        strcpy(pconf->dbpass,optarg);
        break;
      case 'm':
        pconf->maxconns = atoi(optarg);
        break;
      case 'w':
        pconf->workthreadnum = atoi(optarg);
        break;
      case 'l':
        pconf->loglevel = atoi(optarg);
        break;
      case 'd':
        strcpy(pconf->desc,optarg);
        break;
      case 0:
        printf("verbose daemonmode : %d\n",pconf->daemonmode);
        break;
      default:
        printf("unknow option %c",c);
        return 1;
    }  
  }
  
  return 0;
}

int start_server(struct srvcnf *pconf,DATA_CALLBACK pfn_data_callback)
{
  struct srvcnf cnf = *pconf;
  char logpath[150] = {0} ;

  g_pfn_data_callback = pfn_data_callback ;

  /*get work directory*/
  char curpath[100]={0};
  getcwd(curpath,sizeof(curpath));


  /*create logpath*/
  sprintf(logpath,"%s/log",curpath) ;
  if (access(logpath,0) != 0){
    if (mkdir(logpath,0755) != 0){
      perror("create logpath failed");
      return 1;
    }
  }

  /*initalization logger*/
  initlog(cnf.daemonmode,cnf.loglevel,logpath);

  /* enter dameon runing mode*/
  if (cnf.daemonmode && daemon_init()<0){
     WRITE_DEBUG("deamon startup failed,process terminated!");
     return 1;
  }

  SERVERINFO *s = create_server();
  if  ( NULL == s){
    WRITE_DEBUG("create_server failed");
    return 1;
  }

  int buffersize = 1024 ;
  set_serverinfo(s,T_PORT,&cnf.port);
  set_serverinfo(s,T_READBUFFERSIZE,&buffersize);
  set_serverinfo(s,T_WRITEBUFFERSIZE,&buffersize);
  set_serverinfo(s,T_WORKTHREAD_NUM,&cnf.workthreadnum);
  set_serverinfo(s,T_MAXCONNS,&cnf.maxconns);
  set_serverinfo(s,T_DATA_CALLBACK,on_dispatch);

  struct dbinfo info ;
  strcpy(info.dbserver,cnf.dbserver);
  strcpy(info.dbuser,cnf.dbuser);
  strcpy(info.dbpass,cnf.dbpass);
  strcpy(info.default_database,cnf.default_database);
  info.dbport = cnf.dbport;
  setdbinfo(&info);


  WRITE_DEBUG("%s started listening on %d ...",cnf.desc,cnf.port);
  start(s);

  close_db();

  return 0;

}


GAMEPROC(f_login)
{
  int ret = 0;
  int response = 1;
  GET_MAIN_SUB_CMD
 
  CMD_LOGIN *cmd = (CMD_LOGIN *)(DATAADDR);

  char sql[1024];
  sprintf(sql, "SELECT * FROM Accounts WHERE UName = '%s' AND UPasswd = '%s'",cmd->szUserName,cmd->szPassWord);
  MYSQL_RES *res = query_db(sql);
  if (NULL == res) return 1;
  MYSQL_ROW row  = mysql_fetch_row(res);
  mysql_free_result(res);

  if (row) response = 0;

  BYTE *buffer = NULL ;
  int packlen  = create_packet(&buffer,wMCMD,wSCMD,(BYTE *)&response,sizeof(response));
  if (NULL == buffer) return ret;  
  ret = send_packet(item->sfd,buffer,packlen);

  return 0;
}


GAMEPROC(f_reg)
{
  WRITE_DEBUG("recv f_reg %d bytes",len);
  return 0;
}

GAMEPROC(f_userinfo)
{


  WRITE_DEBUG("recv f_userinfo %d bytes",len);
  return 0;
}

int on_dispatch(DISPATCH_VARS)
{
   if (NULL == data) return 1;
   
   MYSQL *mysql = (MYSQL *)pthread_getspecific(mysql_key);
   if (NULL == mysql){
     mysql = mysql_init(NULL);
     pthread_setspecific(mysql_key,mysql);
     connect_db();
   } 
   
   GET_MAIN_SUB_CMD

   int ret = -1;

   switch (wSCMD){
     case C_LOGIN:ret = f_login(V_DISPATCH_VARS);break;
     case C_REG:ret = f_reg(V_DISPATCH_VARS);break;
     case C_USERINFO:ret = f_userinfo(V_DISPATCH_VARS);break;
     default:
       if (NULL != g_pfn_data_callback){
         ret = g_pfn_data_callback(V_DISPATCH_VARS);
       }
       break;
  }

  return ret;
}
